from docx import Document
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from collections import OrderedDict
import io
async def copy_run_properties(source_run, target_run,is_comment=False):
    rPr = source_run._element.get_or_add_rPr()
    new_rPr = target_run.get_or_add_rPr()

    for rFonts in rPr.findall(qn('w:rFonts')):
        new_rFonts = OxmlElement('w:rFonts')
        if rFonts.get(qn('w:ascii')):
            new_rFonts.set(qn('w:ascii'), rFonts.get(qn('w:ascii')))
        if rFonts.get(qn('w:hAnsi')):
            new_rFonts.set(qn('w:hAnsi'), rFonts.get(qn('w:hAnsi')))
        if rFonts.get(qn('w:eastAsia')):
            new_rFonts.set(qn('w:eastAsia'), rFonts.get(qn('w:eastAsia')))
        if rFonts.get(qn('w:cs')):
            new_rFonts.set(qn('w:cs'), rFonts.get(qn('w:cs')))
        if rFonts.get(qn('w:hint')):
            new_rFonts.set(qn('w:hint'), rFonts.get(qn('w:hint')))
        new_rPr.append(new_rFonts)

    # 应用颜色属性
    if is_comment:
        new_color = OxmlElement('w:color')
        new_color.set(qn('w:val'), '346fe4')
        new_rPr.append(new_color)
    else:
        for color in rPr.findall(qn('w:color')):
            new_color = OxmlElement('w:color')
            new_color.set(qn('w:val'), color.get(qn('w:val')))
            new_rPr.append(new_color)

    # 应用字体大小属性
    for sz in rPr.findall(qn('w:sz')):
        new_sz = OxmlElement('w:sz')
        new_sz.set(qn('w:val'), sz.get(qn('w:val')))
        new_rPr.append(new_sz)

    for szCs in rPr.findall(qn('w:szCs')):
        new_szCs = OxmlElement('w:szCs')
        new_szCs.set(qn('w:val'), szCs.get(qn('w:val')))
        new_rPr.append(new_szCs)

    # 应用字体粗细属性
    for b in rPr.findall(qn('w:b')):
        new_b = OxmlElement('w:b')
        new_rPr.append(new_b)

    for bCs in rPr.findall(qn('w:bCs')):
        new_bCs = OxmlElement('w:bCs')
        new_rPr.append(new_bCs)

async def split_word_to_run(paragraph, word):
    # 拼接所有Run文本以找到匹配文本的完整位置
    full_text = ''.join(run.text for run in paragraph.runs)
    # print(full_text)
    # 找到匹配文本在完整文本中的开始和结束位置
    start_index = full_text.find(word)
    end_index = start_index + len(word)

    current_index = 0
    for run in paragraph.runs:
        run_text = run.text
        run_start = current_index
        run_end = current_index + len(run_text)

        # 检查Run是否包含匹配文本的开始部分
        if start_index >= run_start and start_index < run_end:
            # 如果匹配文本在这个Run中结束
            if end_index <= run_end:
                # print('结束：')
                # print(run_text[start_index-run_start:end_index-run_start])

                # 分割运行，将匹配词前后文本分开
                pre_text = run.text[:start_index-run_start]
                match_text = word
                post_text = run.text[end_index-run_start:]
                    # 清除当前Run的文本
                run.text = ''
                # 如果“匹配词”之前有文本，添加一个新的Run
                if pre_text:
                    new_run = OxmlElement('w:r')
                    run._r.addnext(new_run)
                    new_text = OxmlElement('w:t')
                    new_text.text = pre_text
                    new_run.append(new_text)
                    await copy_run_properties(run, new_run)
                # 添加包含“匹配词”的Run
                match_run = OxmlElement('w:r')
                if pre_text:
                    new_run.addnext(match_run)
                else:
                    run._r.addnext(match_run)
                match_text_element = OxmlElement('w:t')
                match_text_element.text = match_text
                match_run.append(match_text_element)
                # copy_run_properties(run, match_run, True)
                await copy_run_properties(run, match_run)
                # 如果“匹配词”之后有文本，添加一个新的Run
                if post_text:
                    new_run = OxmlElement('w:r')
                    match_run.addnext(new_run)
                    new_text = OxmlElement('w:t')
                    new_text.text = post_text
                    new_run.append(new_text)
                    await copy_run_properties(run, new_run)

                break
            else:
                # 如果匹配文本在这个Run中开始但未结束
                # print('开始：')
                # print(run_text[start_index-run_start:])
                run.text = run_text[:start_index-run_start]
                start_index = run_end  # 更新匹配文本的开始位置
        elif start_index == 0 and end_index == 0:
            new_text = OxmlElement('w:t')
            new_text.text = ""
            run._r.append(new_text)
            new_rPr = run._r.get_or_add_rPr()
            new_color = OxmlElement('w:color')
            new_color.set(qn('w:val'), '346fe4')
            new_rPr.append(new_color)
        current_index += len(run_text)
    if not paragraph.runs and not word:
        new_run = OxmlElement('w:r')
        new_text = OxmlElement('w:t')
        new_text.text = ""
        new_run.append(new_text)
        new_rPr = new_run.get_or_add_rPr()
        new_color = OxmlElement('w:color')
        new_color.set(qn('w:val'), '346fe4')
        new_rPr.append(new_color)
        paragraph._p.append(new_run)

